﻿// <copyright file="DataPage.cs" company="Sinclair Community College">
// Copyright 2010 Sinclair Community College
// </copyright>
// <originalAuthor>Patrick S. Seymour (patrick.seymour@gmail.com)</originalAuthor>

namespace SinclairCC.AppV
{
    using System;
    using System.Diagnostics.CodeAnalysis;

    /// <summary>
    /// This class represents a data page in a CP file section.
    /// </summary>
    internal class DataPage
    {
        /// <summary>
        /// This field is reserved and is initialized to 0x00000001.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "This field is marked as reserved in the App-V File Format Specification.")]
        private byte[] reserved1;

        /// <summary>
        /// This field is reserved and is initialized to all zeroes.
        /// </summary>
        [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "This field is marked as reserved in the App-V File Format Specification.")]
        private byte[] reserved2;

        /// <summary>
        /// The byte offset inside the CP file to the next page for the section.
        /// </summary>
        /// <remarks>
        /// This value is relative to the start of the CP file. If there are no
        /// more pages in the linked-list, the value of this field will be 0xFFFFFFFF.
        /// </remarks>
        private uint nextPageOffset;

        /// <summary>
        /// The actual content of the data page.
        /// </summary>
        private byte[] data;

        /// <summary>
        /// Initializes a new instance of the DataPage class.
        /// </summary>
        /// <param name="fileReader">
        /// A binary reader that points to the CP file.
        /// </param>
        /// <param name="bytesToRead">
        /// The number of bytes to read from the BinaryReader object.
        /// </param>
        public DataPage(System.IO.BinaryReader fileReader, int bytesToRead)
        {
            this.ReadSection(fileReader, bytesToRead);
        }
        
        /// <summary>
        /// Gets the raw data from the data page.
        /// </summary>
        public byte[] Data
        {
            get { return this.data; }
        }

        /// <summary>
        /// Gets the byte offset inside the CP file to the next page for the section.
        /// </summary>
        /// <remarks>
        /// This value is relative to the start of the CP file. If there are no
        /// more pages in the linked-list, the value of this field will be 0xFFFFFFFF.
        /// </remarks>
        public uint NextPageOffset
        {
            get { return this.nextPageOffset; }
        }

        /// <summary>
        /// Reads the actual data for this section from the file.
        /// </summary>
        /// <param name="fileReader">
        /// A BinaryReader that points to the CP file.
        /// </param>
        /// <param name="byteCount">
        /// The number of bytes to read from the BinaryReader object.
        /// </param>
        private void ReadSection(System.IO.BinaryReader fileReader, int byteCount)
        {
            this.reserved1 = fileReader.ReadBytes(4);
            this.reserved2 = fileReader.ReadBytes(4);
            this.nextPageOffset = fileReader.ReadUInt32();
            this.data = new byte[byteCount];
            fileReader.Read(this.data, 0, this.data.Length);
        }
    }
}
